#pragma once

#include <iostream>
#include <string>
#include <functional>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <cstdlib>

#include <unistd.h>
#include <pthread.h>

namespace YzcThread
{
    using func_t = std::function<void *(void *)>;
    const int num = 128;

    class Thread
    {
    private:
        // 由于静态方法只能调用静态成员变量和静态成员方法所以，我们不能直接_func(args)。这个不是静态成员
        static void *start_routine(void *_this) // 类内静态成员，参数没有this指针
        {
            // 通过传入的args强制转化为Thread*来获取当前调用的函数和参数
            Thread *thread = static_cast<Thread *>(_this);
            return thread->_func(thread->_args);
        }

    public:
        // 构造函数
        Thread()
        {
            char namebuffer[num];
            snprintf(namebuffer, sizeof(namebuffer), "thread-%d", threadnum++);
            _name = namebuffer;
        }

        // 线程开始运行函数
        void start(func_t func = nullptr, void *args = nullptr)
        {
            _func = func;
            _args = args;
            int n = pthread_create(&_tid, nullptr, start_routine, this);
            assert(n == 0);
            (void)n;
        }

        // 线程等待函数
        void join()
        {
            int n = pthread_join(_tid, nullptr);
            assert(n == 0);
            (void)n;
        }

        std::string threadname()
        {
            return _name;
        }

        ~Thread()
        {
            // do nothing
        }

    private:
        std::string _name; // 线程的名字
        pthread_t _tid;    // 线程的tid，即在虚拟内存线程TCB的起始地址
        func_t _func;      // 线程执行的方法
        void *_args;       // 线程方法的参数

        static int threadnum; // 线程的编号
    };
    int Thread::threadnum = 1;
}